/***************************************************************************//**
 * @file MultiTimer.c
 * @brief for timeing decommand
 * @author ze .
 * @date  2022/6/30.
 * @copyright Copyright 
 ******************************************************************************/

#ifndef _MULTI_TIMER_H_
#define _MULTI_TIMER_H_

#include <stdint.h>
#include "stdio.h"

#ifdef __cplusplus  
extern "C" {  
#endif

typedef enum
{
    EN_MULTITIMER_STATUS_IDLE = 0, //软定时器空闲
    EN_MULTITIMER_STATUS_RUN_BACK = 1,//软定时器在后台运行
    EN_MULTITIMER_STATUS_RUN_FRONT =2 ,//指在前端（第一个）运行，会有定时器硬比较中断
    EN_MULTITIMER_STATUS_EXPIRED 

}MULTITIMER_STATUS_EN;

//typedef struct MultiTimerHandle MultiTimer;
typedef struct MultiTimerHandle { //Info0506 按结构体对齐规则，4*8 =32字节？？
    uint8_t status; //见MULTITIMER_STATUS_EN，表示该定时器的状态
    uint16_t Handle;//句柄，需保证在硬定时器（软定时器组）下的唯一性，最好是定义在同一个位置
    uint32_t Time; //计时时间，用于debug，或许可去掉
    uint64_t deadline;
    void (*callback)(struct MultiTimerHandle*,void*);
    void* userData;
    struct MultiTimerHandle* next;    
}MultiTimer;

typedef void (*MultiTimerCallback_t)(MultiTimer* timer, void* userData);
typedef uint64_t (*sysTicksGetFunction_t)(void);
typedef void  (*timerNewStartedFunction_t) (MultiTimer* timer);
typedef void  (*timerStopFunction_t) (MultiTimer* timer);


typedef struct //Info0506 按结构体对齐规则，4*6 =24字节，将u8置顶，是否节省内存？
{
    /* Timer handle list head.链表长度 不宜太长，否则遍历时for循环次数多 */
    MultiTimer* timerList ; 
    /* Timer tick */
    sysTicksGetFunction_t sysTicksGetFunction ; //获取当前系统滴答时间的回调函数
    timerNewStartedFunction_t timerNewStartedFunction;//开启硬件定时器的比较中断
    timerStopFunction_t  timerStopFunction; //停止硬件定时器的比较中断，需注意形参是否为NULL
    uint8_t        isCriticalProtect;//是否开启临界保护，若该.h中的api被中断内调用，需开启
    uint8_t        byHandle;//句柄，标识硬定时器，或软定时器组
}MULTITIMER_INST_ST;


/**
 * @brief Start the timer work, add the handle into work list.
 * 
 * @param inst  instance for multiTimer
 * @param timer target handle strcut.
 * @param timing Set the start time.
 * @param callback deadline callback.
 * @param userData user data.
 * @param sRepeatCheck 是否对链表内重复的数据进行检测，否 以节约时间
 * @param isTimingDeadline 是否timing字段为deadline结束时间,直接指定deadline结束，用于时分多址
 * @return int >: idx, -1: fail.
 */
int MultiTimerStart(MULTITIMER_INST_ST* inst, MultiTimer* timer, uint64_t timing, MultiTimerCallback_t callback, void* userData,uint8_t isRepeatCheck,uint8_t isTimingDeadline);

/**
 * @brief Stop the timer work, remove the handle off work list.
 * 
 * @param inst  instance for multiTimer
 * @param timer target handle strcut.
 * @return int >= 0 idx, -1: fail.
 */
int MultiTimerFind(MULTITIMER_INST_ST* inst,MultiTimer* timer);

/**
 * @brief Stop the timer work, remove the handle off work list.
 * 
 * @param inst  instance for multiTimer
 * @param timer target handle strcut.
 * @param isCallbackExpire 是否直接回调溢出函数
 * @return int 0: success, -1: fail.
 */
int MultiTimerStop(MULTITIMER_INST_ST* inst,MultiTimer* timer,uint8_t isCallbackExpire);

/**
 * @brief Stop the timer work, remove all the handle off work list.
 * 
 * @param inst  instance for multiTimer
 * @return int 0: success, -1: fail.
 */
int MultiTimerStopAll(MULTITIMER_INST_ST* inst);

/**
 * @brief Check the timer expried and call callback.
 * 
 * @param inst  instance for multiTimer
 * @return int The next timer expires.
 */
int MultiTimerYield(MULTITIMER_INST_ST* inst);



#ifdef __cplusplus
} 
#endif

#endif
